package com.hducms.cms.service.impl;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hducms.cms.dao.ChannelDao;
import com.hducms.cms.dao.ChannelExtDao;
import com.hducms.cms.dao.ChannelTxtDao;
import com.hducms.cms.entity.main.Channel;
import com.hducms.cms.entity.main.ChannelExt;
import com.hducms.cms.entity.main.ChannelTxt;
import com.hducms.cms.entity.main.CmsGroup;
import com.hducms.cms.entity.main.CmsModel;
import com.hducms.cms.entity.main.CmsUser;
import com.hducms.cms.entity.main.CmsUserSite;
import com.hducms.cms.service.ChannelDeleteChecker;
import com.hducms.cms.service.ChannelExtService;
import com.hducms.cms.service.ChannelService;
import com.hducms.cms.service.ChannelTxtService;
import com.hducms.cms.service.CmsGroupService;
import com.hducms.cms.service.CmsModelService;
import com.hducms.cms.service.CmsSiteService;
import com.hducms.cms.service.CmsUserService;
import com.hducms.common.page.Pagination;

@Service
@Transactional
public class ChannelServiceImpl implements ChannelService {

	@Transactional(readOnly = true)
	public List<Channel> getTopList(boolean hasContentOnly) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("hasContentOnly", hasContentOnly);
		List<Channel> channels =dao.getTopList(params);
		for (Channel channel : channels) {
			Set<Channel> children = new HashSet<Channel>();
//			Set<Channel> topChilren = channel.getChild();
			for (Channel child : channel.getChild()) {
				child = dao.findById(child.getId());
				children.add(child);
			}
			channel.setChild(children);
		}
		return channels;
	}
	@Transactional(readOnly = true)
	public List<Channel> getTopListByRigth(Integer userId, 
			boolean hasContentOnly) {
		CmsUser user = cmsUserMng.findById(userId);
		CmsUserSite us = user.getUserSite();
		if (us.getAllChannel()) {
			return getTopList(hasContentOnly);
		} else {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("userId", userId);
			if (hasContentOnly) {
				param.put("hasContentOnly", 1);
			}
			
			List<Channel> channels =dao.getTopListByRigth(param);
//			for (Channel channel : channels) {
//				Set<Channel> children = new HashSet<Channel>();
////				Set<Channel> topChilren = channel.getChild();
//				for (Channel child : channel.getChild()) {
//					child = dao.findById(child.getId());
//					children.add(child);
//				}
//				channel.setChild(children);
//			}
			return channels;

		}
	}
	//
	//	@Transactional(readOnly = true)
	//	public List<Channel> getTopListForTag(Integer siteId, boolean hasContentOnly) {
	//		return dao.getTopList(siteId, hasContentOnly, true, true);
	//	}
	//
	//	@Transactional(readOnly = true)
	//	public Pagination getTopPageForTag(Integer siteId, boolean hasContentOnly,
	//			int pageNo, int pageSize) {
	//		return dao.getTopPage(siteId, hasContentOnly, false, false, pageNo,
	//				pageSize);
	//	}
	//
	@Transactional(readOnly = true)
	public List<Channel> getChildList(Integer parentid, boolean hasContentOnly) {
		Map<String, Object> params = new HashMap<String, Object>(2);
		params.put("parentId", parentid);
		if (hasContentOnly) {
			params.put("hasContentOnly", hasContentOnly);
		}
		return dao.getChildList(params);
	}

	@Transactional(readOnly = true)
	public List<Channel> getChildListByRight(Integer userId, 
			Integer parentId, boolean hasContentOnly) {
		CmsUser user = cmsUserMng.findById(userId);
		CmsUserSite us = user.getUserSite();
		if (us.getAllChannel()) {
			return getChildList(parentId, hasContentOnly);
		} else {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("userId", userId);
			param.put("parentId", parentId);
			if (hasContentOnly) {
				param.put("hasContentOnly", 1);
			}
			return dao.getChildListByRight(param);
		}
	}

	//	@Transactional(readOnly = true)
	//	public List<Channel> getChildListForTag(Integer parentId,
	//			boolean hasContentOnly) {
	//		return dao.getChildList(parentId, hasContentOnly, true, true);
	//	}
	//
	//	@Transactional(readOnly = true)
	//	public Pagination getChildPageForTag(Integer parentId,
	//			boolean hasContentOnly, int pageNo, int pageSize) {
	//		return dao.getChildPage(parentId, hasContentOnly, true, true, pageNo,
	//				pageSize);
	//	}
	//
	@Transactional(readOnly = true)
	public Channel findById(Integer id) {
		Channel entity = dao.findById(id);
		return entity;
	}
	//
	//	@Transactional(readOnly = true)
	//	public Channel findByPath(String path, Integer siteId) {
	//		return dao.findByPath(path, siteId, false);
	//	}
	//
	//	@Transactional(readOnly = true)
	//	public Channel findByPathForTag(String path, Integer siteId) {
	//		return dao.findByPath(path, siteId, true);
	//	}
	//
	public Channel save(Channel bean, ChannelExt ext, ChannelTxt txt,
			Integer[] viewGroupIds, Integer[] contriGroupIds,
			Integer[] userIds, Integer siteId, Integer parentId,
			Integer modelId,Integer[]modelIds,String[] tpls) {
		if (parentId != null) {
			bean.setParent(findById(parentId));
			bean.setParentid(bean.getParent().getId());
		}
		bean.setSite(cmsSiteMng.findById(siteId));
		CmsModel model = cmsModelMng.findById(modelId);
		bean.setModel(model);
		bean.setModelid(model.getId());
		bean.setHasContent(model.getHasContent());
		bean.init();
		if(bean.getParent()!=null){
			int rgt = bean.getParent().getRgt()+2;
			dao.updatetree(bean.getParent().getRgt());
			dao.updateParetntree(bean.getParent().getRgt());
			//			dao.updatetree_r(bean.getParent().getRgt());
			bean.setRgt(rgt-1);
			bean.setLft(rgt-2);
		}
		else {
			int rgt=dao.getMaxRgt();
			bean.setLft(rgt+1);
			bean.setRgt(rgt+2);
		}
		dao.save(bean);
		ext.setId(bean.getId());
		txt.setId(bean.getId());
		channelExtMng.save(ext);
		channelTxtMng.save(txt);
		//		CmsGroup g;
		if (viewGroupIds != null && viewGroupIds.length > 0) {
			for (Integer gid : viewGroupIds) {
				Map<String, Object> params = new HashMap<String, Object>(2);
				params.put("channelid", bean.getId());
				params.put("groupid", gid); 
				dao.saveViewGroup(params);
				//				g = cmsGroupMng.findById(gid);
				//				bean.addToViewGroups(g);
			}
		}
		if (contriGroupIds != null && contriGroupIds.length > 0) {
			for (Integer gid : contriGroupIds) {
				Map<String, Object> params = new HashMap<String, Object>(2);
				params.put("channelid", bean.getId());
				params.put("groupid", gid); 
				dao.saveContriGroup(params);
				//				g = cmsGroupMng.findById(gid);
				//				bean.addToContriGroups(g);
			}
		}
		if (modelIds != null && modelIds.length > 0) {
			Map<String, Object> params = new HashMap<String, Object>(2);
			params.put("id", bean.getId());
			Set<Integer> modelSet = new HashSet<Integer>();
			for (Integer i : modelIds) {
				modelSet.add(i);
			}
			params.put("list", modelSet); 
			dao.saveChannelModel(params);

		}
		//		CmsUser u;
		if (userIds != null && userIds.length > 0) {
			for (Integer uid : userIds) {
				Map<String, Object> params = new HashMap<String, Object>(2);
				params.put("channelid", bean.getId());
				params.put("userid", uid); 
				dao.saveChannelUser(params);
				//				u = cmsUserMng.findById(uid);
				//				bean.addToUsers(u);
			}
		}
		return bean;
	}
	//
	public Channel update(Channel bean, ChannelExt ext, ChannelTxt txt,
			Integer[] viewGroupIds, Integer[] contriGroupIds,
			Integer[] userIds, Integer parentId, Map<String, String> attr,Integer[]modelIds,String[] tpls) {
		// 更新主表
		//		Updater<Channel> updater = new Updater<Channel>(bean);
		//		bean = dao.updateByUpdater(updater);
		dao.update(bean);
		// 更新父栏目
		//		Channel parent;
		//		if (parentId != null) {
		//			parent = findById(parentId);
		//		} else {
		//			parent = null;
		//		}
		//		bean.setParent(parent);
		// 更新扩展表
		ext.setId(bean.getId());
		channelExtMng.update(ext);
		// 更新文本表
		if (null != txt.getTxt()||null != txt.getTxt1()||null != txt.getTxt2()||
				null != txt.getTxt3()) {
			txt.setId(bean.getId());
			channelTxtMng.update(txt);
		}

		//		// 更新属性表
		//		Map<String, String> attrOrig = bean.getAttr();
		//		attrOrig.clear();
		//		attrOrig.putAll(attr);
		// 更新浏览会员组关联
		//		for (CmsGroup g : bean.getViewGroups()) {
		//			g.getViewChannels().remove(bean);
		//		}
		//		bean.getViewGroups().clear();
		//		if (viewGroupIds != null && viewGroupIds.length > 0) {
		//			CmsGroup g;
		//			for (Integer gid : viewGroupIds) {
		//				g = cmsGroupMng.findById(gid);
		//				bean.addToViewGroups(g);
		//			}
		//		}
		dao.deleteVById(bean.getId());
		if (viewGroupIds!=null) {
			for (Integer temp : viewGroupIds) {
				Map<String, Object> params = new HashMap<String, Object>(2);
				params.put("channelid", bean.getId());
				params.put("groupid", temp);
				dao.saveViewGroup(params);
			}
		}
		// 更新投稿会员组关联
		//		for (CmsGroup g : bean.getContriGroups()) {
		//			g.getContriChannels().remove(bean);
		//		}
		//		bean.getContriGroups().clear();
		//		if (contriGroupIds != null && contriGroupIds.length > 0) {
		//			CmsGroup g;
		//			for (Integer gid : contriGroupIds) {
		//				g = cmsGroupMng.findById(gid);
		//				bean.addToContriGroups(g);
		//			}
		//		}
		//		bean.getChannelModels().clear();
		//		if (modelIds != null && modelIds.length > 0) {
		//			for (int i=0;i<modelIds.length;i++) {
		//				CmsModel m = cmsModelMng.findById(modelIds[i]);
		//				bean.addToChannelModels(m, tpls[i]);
		//			}
		//		}

		dao.deleteCById(bean.getId());
		if (contriGroupIds!=null) {
			for (Integer temp : contriGroupIds) {
				Map<String, Object> params = new HashMap<String, Object>(2);
				params.put("channelid", bean.getId());
				params.put("groupid", temp);
				dao.saveContriGroup(params);;
			}
		}
		// 更新管理员关联
		//		for (CmsUser u : bean.getUsers()) {
		//			u.getChannels().remove(bean);
		//		}
		//		bean.getUsers().clear();
		//		if (userIds != null && userIds.length > 0) {
		//			CmsUser u;
		//			for (Integer uid : userIds) {
		//				u = cmsUserMng.findById(uid);
		//				bean.addToUsers(u);
		//			}
		//		}
		dao.deleteUserById(bean.getId());
		if (userIds!=null) {	
			for (Integer temp : userIds) {
				Map<String, Object> params = new HashMap<String, Object>(2);
				params.put("channelid", bean.getId());
				params.put("userid", temp);
				dao.saveChannelUser(params);
			}
		}	
		return bean;
	}
	//
	public Channel deleteById(Integer id) {
		//		Channel entity = dao.findById(id);
		//		for (CmsGroup group : entity.getViewGroups()) {
		//			group.getViewChannels().remove(entity);
		//		}
		//		for (CmsGroup group : entity.getContriGroups()) {
		//			group.getContriChannels().remove(entity);
		//		}
		Channel bean = dao.findById(id);
		channneExtDao.deleteById(id);
		channelTxtDao.deleteById(id);
		dao.deleteChannelUsers(id);
		dao.deleteCById(id);
		dao.deleteVById(id);
		dao.deleteById(id);
		return bean;
	}

	public Channel[] deleteByIds(Integer[] ids) {
		Channel[] beans = new Channel[ids.length];
		for (int i = 0, len = ids.length; i < len; i++) {
			beans[i] = deleteById(ids[i]);
		}
		return beans;
	}

	public String checkDelete(Integer id) {
		String msg = null;
		for (ChannelDeleteChecker checker : deleteCheckerList) {
			msg = checker.checkForChannelDelete(id);
			if (msg != null) {
				return msg;
			}
		}
		return msg;
	}

	@Override
	public CmsGroup findViewGroupById(Integer id) {
		return dao.findViewGroupById(id);
	}
	@Override
	public CmsGroup findContriGroupById(Integer id) {
		return dao.findContriGroupById(id);
	}
	@Override
	public Integer[] findViewGroupIdById(Integer id) {
		return dao.findViewGroupIdById(id);
	}
	@Override
	public Integer[] findContriGroupIdById(Integer id) {
		return dao.findContriGroupIdById(id);
	}
	@Override
	public Integer[] findUserIdById(int id) {
		return dao.findUserIdById(id);
	}
	@Override
	public CmsUser findUserById(Integer id) {
		return dao.findUserById(id);
	}


	//	public Channel[] updatePriority(Integer[] ids, Integer[] priority) {
	//		int len = ids.length;
	//		Channel[] beans = new Channel[len];
	//		for (int i = 0; i < len; i++) {
	//			beans[i] = findById(ids[i]);
	//			beans[i].setPriority(priority[i]);
	//		}
	//		return beans;
	//	}
	//
	//	private List<ChannelDeleteChecker> deleteCheckerList;

	//	public void setDeleteCheckerList(
	//			List<ChannelDeleteChecker> deleteCheckerList) {
	//		this.deleteCheckerList = deleteCheckerList;
	//	}


	private CmsSiteService cmsSiteMng;
	private CmsModelService cmsModelMng;
	private ChannelExtService channelExtMng;
	private ChannelTxtService channelTxtMng;
	private CmsUserService cmsUserMng;
	private CmsGroupService cmsGroupMng;
	private ChannelDao dao;
	@Autowired
	private ChannelExtDao channneExtDao;
	@Autowired
	private ChannelTxtDao channelTxtDao ;
	private List<ChannelDeleteChecker> deleteCheckerList;

	@Autowired
	public void setDeleteCheckerList(
			List<ChannelDeleteChecker> deleteCheckerList) {
		this.deleteCheckerList = deleteCheckerList;
	}
	@Autowired
	public void setCmsSiteMng(CmsSiteService cmsSiteMng) {
		this.cmsSiteMng = cmsSiteMng;
	}

	@Autowired
	public void setCmsModelMng(CmsModelService cmsModelMng) {
		this.cmsModelMng = cmsModelMng;
	}

	@Autowired
	public void setChannelExtMng(ChannelExtService channelExtMng) {
		this.channelExtMng = channelExtMng;
	}

	@Autowired
	public void setChannelTxtMng(ChannelTxtService channelTxtMng) {
		this.channelTxtMng = channelTxtMng;
	}

	@Autowired
	public void setCmsUserMng(CmsUserService cmsUserMng) {
		this.cmsUserMng = cmsUserMng;
	}

	@Autowired
	public void setCmsGroupMng(CmsGroupService cmsGroupMng) {
		this.cmsGroupMng = cmsGroupMng;
	}

	@Autowired
	public void setDao(ChannelDao dao) {
		this.dao = dao;
	}

	@Override
	public CmsModel findModelByid(int modelId) {
		return dao.findModelByid(modelId);
	}
	@Override
	public ChannelExt findChannelExt(Integer id) {
		return dao.getChannelName(id);
	}
	@Override
	public Integer[] findViewChannelIdsByGroupId(int id) {
		// TODO Auto-generated method stub
		return dao.findViewChannelIdsByGroupId(id);
	}
	@Override
	public Integer[] getViewGroupIds(int channelId) {
		return dao.findViewGroupIdById(channelId);
	}



}
